package com.tjcd.project.library_base.common.utils;

import android.annotation.SuppressLint;
import android.net.Uri;

import com.alibaba.sdk.android.oss.ClientConfiguration;
import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.blankj.utilcode.util.TimeUtils;
import com.tjcd.project.library_base.BaseApplication;
import com.tjcd.project.library_base.common.baseBean.OssUploadFileBean;
import com.tjcd.project.library_base.common.upload.bean.UploadBean;

import java.io.File;
import java.util.ArrayList;

/**
 * @Author jiangKunKun
 * @CreateDate 2021/7/13
 * @Description oss上传图片
 * @SpittingGrooves
 */
public class OssUpLoadUtil {

    /**
     * 文件地址
     */
    private ArrayList<File> mFiles = new ArrayList<>();
    /**
     * Uri地址
     */
    private ArrayList<Uri> mUris = new ArrayList<>();
    /**
     * 文件key
     */
    private ArrayList<UploadBean> mObjectKey = new ArrayList<>();

    private OSSAsyncTask mOssTask;

    /**
     * File类型上传
     * @param ossUploadFileBean 基础配置
     * @param files 多个上传
     * @param ossUpLoadListener 监听
     */
    public void ossUpLoadFile(OssUploadFileBean ossUploadFileBean, ArrayList<File> files, ossUpLoadListener ossUpLoadListener){
        mFiles.clear();
        mObjectKey.clear();
        mFiles.addAll(files);
        ossUpLoadUtil(ossUploadFileBean, ossUpLoadListener, 1);
    }
    /**
     * File类型上传
     * @param ossUploadFileBean 基础配置
     * @param file 单个上传
     * @param ossUpLoadListener 监听
     */
    public void ossUpLoadFile(OssUploadFileBean ossUploadFileBean, File file, ossUpLoadListener ossUpLoadListener){
        mFiles.clear();
        mObjectKey.clear();
        mFiles.add(file);
        ossUpLoadUtil(ossUploadFileBean, ossUpLoadListener, 1);
    }

    /**
     * Uri类型上传
     * @param ossUploadFileBean 基础配置
     * @param uris 多个上传
     * @param ossUpLoadListener 监听
     */
    public void ossUpLoadUri(OssUploadFileBean ossUploadFileBean, ArrayList<Uri> uris, ossUpLoadListener ossUpLoadListener){
        mUris.clear();
        mObjectKey.clear();
        mUris.addAll(uris);
        ossUpLoadUtil(ossUploadFileBean, ossUpLoadListener, 2);
    }
    /**
     * Uri类型上传
     * @param ossUploadFileBean 基础配置
     * @param uri 单个上传
     * @param ossUpLoadListener 监听
     */
    public void ossUpLoadUri(OssUploadFileBean ossUploadFileBean, Uri uri, ossUpLoadListener ossUpLoadListener){
        mUris.clear();
        mObjectKey.clear();
        mUris.add(uri);
        ossUpLoadUtil(ossUploadFileBean, ossUpLoadListener, 2);
    }

    /**
     *
     * @param ossUploadFileBean 基础信息
     * @param ossUpLoadListener 监听
     */
    /**
     *
     * @param ossUploadFileBean 基础信息
     * @param ossUpLoadListener 监听
     * @param type 1.file 2.uri
     */
    @SuppressLint("NotConstructor")
    private void ossUpLoadUtil(OssUploadFileBean ossUploadFileBean, ossUpLoadListener ossUpLoadListener, int type){
        OSSLog.enableLog();
        // 在移动端建议使用STS的方式初始化OSSClient。
        OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(ossUploadFileBean.getAccessKeyId(), ossUploadFileBean.getAccessKeySecret(), ossUploadFileBean.getSecurityToken());
        ClientConfiguration conf = new ClientConfiguration();
        // 连接超时，默认15秒。
        conf.setConnectionTimeout(15 * 1000);
        // socket超时，默认15秒。
        conf.setSocketTimeout(15 * 1000);
        // 最大并发请求书，默认5个。
        conf.setMaxConcurrentRequest(5);
        // 失败后最大重试次数，默认2次。
        conf.setMaxErrorRetry(2);
        OSS oss = new OSSClient(BaseApplication.getInstance(), ossUploadFileBean.getHost(), credentialProvider, conf);

        if (1 == type){
            for (int i = 0; i < mFiles.size(); i++) {
                // 构造上传请求。
                PutObjectRequest put = new PutObjectRequest(ossUploadFileBean.getBucketName(), ossUploadFileBean.getUploadFilePath() +  mFiles.get(i).getName(), mFiles.get(i).getPath());
                // 异步上传时可以设置进度回调。
                put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
                    @Override
                    public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                        if (null != ossUpLoadListener){
                            ossUpLoadListener.onProgress(request, currentSize, totalSize);
                        }
                    }
                });

                mOssTask = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                    @Override
                    public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                        mObjectKey.add(new UploadBean(request.getObjectKey(), ossUploadFileBean.getAliyunDomainDefault() + "/" + request.getObjectKey()));

                        if (mFiles.size() == mObjectKey.size()){ // 成功回调
                            if (null != ossUpLoadListener){
                                ossUpLoadListener.onAllSuccess(mObjectKey);
                            }
                            mOssTask.cancel();
                        }
                        if (null != ossUpLoadListener){
                            ossUpLoadListener.onSingleSuccess(request, result);
                        }
                    }

                    @Override
                    public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                        if (null != ossUpLoadListener){
                            ossUpLoadListener.onFailure(request, clientExcepion, serviceException);
                        }
                        // 请求异常。
                        if (clientExcepion != null) {
                            // 本地异常，如网络异常等。
                            clientExcepion.printStackTrace();
                        }
                        if (serviceException != null) {
                            // 服务异常。
                        }
                        // 果然有一个失败 失败回调
                        mOssTask.cancel();
                    }
                });
            }
        }else if (2 == type){
            for (int i = 0; i < mUris.size(); i++){
                // 构造上传请求。
                PutObjectRequest put = new PutObjectRequest(ossUploadFileBean.getBucketName(), ossUploadFileBean.getUploadFilePath() + TimeUtils.getNowMills(), mUris.get(i));
                // 异步上传时可以设置进度回调。
                put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
                    @Override
                    public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                        if (null != ossUpLoadListener){
                            ossUpLoadListener.onProgress(request, currentSize, totalSize);
                        }
                    }
                });

                mOssTask = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                    @Override
                    public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                        mObjectKey.add(new UploadBean(request.getObjectKey(), ossUploadFileBean.getAliyunDomainDefault() + "/" + request.getObjectKey()));

                        if (mUris.size() == mObjectKey.size()){ // 成功回调
                            if (null != ossUpLoadListener){
                                ossUpLoadListener.onAllSuccess(mObjectKey);
                            }
                            mOssTask.cancel();
                        }
                        if (null != ossUpLoadListener){
                            ossUpLoadListener.onSingleSuccess(request, result);
                        }
                    }

                    @Override
                    public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                        if (null != ossUpLoadListener){
                            ossUpLoadListener.onFailure(request, clientExcepion, serviceException);
                        }
                        // 请求异常。
                        if (clientExcepion != null) {
                            // 本地异常，如网络异常等。
                            clientExcepion.printStackTrace();
                        }
                        if (serviceException != null) {
                            // 服务异常。
                        }
                        // 果然有一个失败 失败回调
                        mOssTask.cancel();
                    }
                });
            }
        }
    }

    public interface ossUpLoadListener {
        /**
         * 进度
         * @param request 请求
         * @param currentSize 目前进度
         * @param totalSize 总进度
         */
        void onProgress(PutObjectRequest request, long currentSize, long totalSize);

        /**
         * 成功
         * @param request 对象
         * @param result 结果
         */
        void onSingleSuccess(PutObjectRequest request, PutObjectResult result);

        /**
         * 全部成功
         * @param objectKey 结果
         */
        void onAllSuccess(ArrayList<UploadBean> objectKey);

        /**
         * 错误
         * @param request 请求
         * @param clientExcepion 客户端异常
         * @param serviceException 服务异常
         */
        void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException);
    }

}
